import {
  ChangeDetectionStrategy,
  Component, ElementRef, EventEmitter,
  Input, OnInit, Output,
  ChangeDetectorRef, Renderer2, ViewChild, AfterViewInit, Optional, Inject
} from "@angular/core";
import {BehaviorSubject, fromEvent, Observable, Subject} from "rxjs";
import {mapTo, startWith} from "rxjs/operators";
import {AvtSortDirective} from "./avt-sort.directive";

type SortMode = 'sort' | 'asc' | 'desc'

export interface SortChange {
  sortStatus: SortMode,
  columnName: string
}

@Component({
  selector: 'th[tbSort], th[tbColumnKey], th[tbFilter]',
  template: `
    <ng-content></ng-content>
    <img *ngIf="tbSort" [attr.src]="currentIconPath" alt="">
    <div *ngIf="tbFilter" (click)="toggleFilter($event)" class="filter-area">
      <svg viewBox="64 64 896 896" focusable="false" fill="currentColor" width="1em" height="1em" data-icon="filter" aria-hidden="true"><path d="M349 838c0 17.7 14.2 32 31.8 32h262.4c17.6 0 31.8-14.3 31.8-32V642H349v196zm531.1-684H143.9c-24.5 0-39.8 26.7-27.5 48l221.3 376h348.8l221.3-376c12.1-21.3-3.2-48-27.7-48z"></path></svg>
    </div>
    <div class="filter-inp"
         [ngStyle]="{'display': (displayInput$ | async) ? 'block' : 'none'}"

    >
      <input   #inp
             placeholder="filter..."
             type="text"
             [(ngModel)]="filterString">
    </div>
  `,
  styles: [
    `
      .filter-inp {
        position: absolute;
        right: 0;
        bottom: -100%;
        height: 30px;
        background: #eee;
        color: #000;
      }
      .filter-area {
        position: absolute;
        height: 100%;
        right: 0;
        top: 0;
        width: 20px;
        background: #344b62;
        display: flex;
        cursor: pointer;
        align-items: center;
        justify-content: center;
      }
      .filter-area>svg {
        width: 12px;
      }
    `
  ],
  changeDetection: ChangeDetectionStrategy.OnPush,
  host: {
    '[class.ml-table-sort-col]': 'tbSort',
    '(click)': 'emitNextSortValue($event)'
  }
})
export class thAddonComponent
  implements OnInit, AfterViewInit{
  filterString = ''
  @Input() tbSort = false
  @Input() tbColumnKey = ''
  @Input() tbFilter = false
  @Output() sortChange: EventEmitter<SortChange> = new EventEmitter()
  @ViewChild('inp', {static: false}) filterInput
  displayInput$ = new BehaviorSubject(false)
  thClick$: Subject<thAddonComponent> = new Subject<thAddonComponent>()
  filterAreaClick$: Subject<thAddonComponent> = new Subject<thAddonComponent>()
  inputOb$: Observable<any>
  iconMap = {
    'sort': 'assets/img/icon/av-icon-sorting.svg',
    'asc': 'assets/img/icon/av-icon-sorting-s-to-l.svg',
    'desc': 'assets/img/icon/av-icon-sorting-l-to-s.svg'
  }
  currentIconPath = ''
  currentMode: SortMode = 'sort'
  static sortMode: SortMode[] = ['sort', 'asc', 'desc' ]

  private getNextSortMode(): SortMode {
    const { sortMode } = thAddonComponent
    const currentIndex = sortMode.indexOf(this.currentMode)
    let nextMode
    if (currentIndex === sortMode.length - 1) {
      nextMode = sortMode[0]
    } else {
      nextMode = sortMode[currentIndex + 1]
    }
    return nextMode
  }
  clickOutSide(isOut) {
    console.log(isOut)
  }
  toggleFilter(ev: any) {
    // 阻止事件冒泡
    ev.stopPropagation()
    this.filterAreaClick$.next(this)
  }

  resetSortMode() {
    this.currentMode = 'sort'
    this.currentIconPath = this.iconMap[this.currentMode]
    this.cdr.detectChanges()
  }


  constructor(private el: ElementRef,
              private cdr: ChangeDetectorRef,
              private rd2: Renderer2,
              @Optional()
              @Inject('MAT_SORT_HEADER_COLUMN_DEF')
              private _columnDef: { name: string },
              @Optional()
              readonly _sort: AvtSortDirective
              ) {}

  ngAfterViewInit() {
    // @ts-ignore
    this.inputOb$ = fromEvent(this.filterInput.nativeElement, 'input').pipe(
      mapTo(this)
    )
  }

  get columnName() {
    return this._columnDef.name;
  }

  ngOnInit() {
    this._sort.registerSorter( this.columnName, this )
    if(this.tbSort) {
      this.currentIconPath = this.iconMap['sort']
    }
    this.rd2.setStyle(this.el.nativeElement, 'position', 'relative')
  }

  emitNextSortValue(ev: any) {
    if (!this.tbSort) return
    if (ev.target.nodeName.toLowerCase() === 'input') return;
    let nextMode = this.getNextSortMode()
    this.currentMode = nextMode
    this.currentIconPath = this.iconMap[nextMode]
    this.thClick$.next(this)
    this.sortChange.emit({
      sortStatus: this.currentMode,
      columnName: this.columnName
    })
  }
}
